﻿#include "View.h"
#include "Globals.h"    // 访问图片、玩家状态等全局变量
#include "UIUtils.h"    // 访问 drawAlpha, button, inputText 等 UI 工具函数
#include "Input.h"      // 访问输入处理函数
#include "GameLogic.h"  // 访问 newGame, loadGame, gameView 等游戏逻辑函数
#include "Network.h"    // 访问 login_user, register_user 等网络函数
#include <stdio.h>      // 用于 printf 调试

// --- 视图函数定义 ---

// 登录视图
void logView() {
    // 如果图形未初始化，则初始化 (例如直接调用时)
    // initgraph(640, 480); // 登录用小窗口? 使用常量 WIDTH, HEIGHT
    // setbkcolor(WHITE); // 设置背景色?
    // cleardevice();

    bool exitLogin = false; // 控制是否退出登录循环
    while (!exitLogin) {
        handle_login_input(&exitLogin); // 处理输入并检查是否需要退出
        login_draw();                   // 绘制登录界面
        Sleep(16);                      // 短暂延迟以防 CPU 占用过高
    }
    // 退出或转换由 handle_login_input 设置 exitLogin 来处理
}

// 注册视图
int registerView(const char* username, const char* password) {
    // 这个函数似乎被设计为*成为*视图本身，而不仅仅是处理注册。
    // 我们让它显示注册屏幕。
    // username/password 参数在此处可能不需要。

    // initgraph(1280, 720); // 使用 WIDTH, HEIGHT 常量

    IMAGE registerImage[6]; // 此视图使用的局部图片数组
    // 如果加载慢，考虑将图片加载移到外部

    bool exitRegister = false;         // 控制是否退出注册循环
    int registrationResult = -1;     // 注册结果: -1:进行中, 0:失败, 1:成功, 2:返回
    loadimage(registerImage, "Assets\\register\\注销背景.png", 1280, 720);
    loadimage(registerImage + 1, "Assets\\register\\黄色按钮.png", 150, 100);
    loadimage(registerImage + 2, "Assets\\register\\黄色按钮.png", 150, 75);
    loadimage(registerImage + 3, "Assets\\register\\白色输入框.png", 450, 30);

    draw_Register_Again(registerImage);

    while (!exitRegister) {
        handle_register_input(&exitRegister, &registrationResult); // 处理输入, 检查确认/返回
        // 在 handle_register_input 内部或之后调用 draw() 来更新输入框内容
        BeginBatchDraw(); // 确保绘制在批处理中
        draw(); // 绘制输入框内容
        EndBatchDraw();
        Sleep(16);
    }

    // 根据 registrationResult 清理或转换
    if (registrationResult == 1) {
        printf("注册成功 (来自视图)。正在返回登录。\n");
        logView(); // 成功后返回登录
    } else if (registrationResult == 2) {
        printf("注册已取消。正在返回登录。\n");
        logView(); // 取消后返回登录
    } else {
        printf("注册失败或状态未知。正在返回登录。\n");
        logView(); // 失败也返回登录
    }
    return registrationResult; // 返回状态 (尽管转换已在上面处理)
}

// 忘记密码/修改密码视图
void forgetView() {
    // initgraph(450, 450); // 如果需要不同尺寸，使用常量
    // setbkcolor(WHITE);
    // cleardevice();

    bool exitForget = false; // 控制是否退出此视图
    while (!exitForget) {
        handle_password_input(&exitForget); // 处理输入
        password_draw();                    // 绘制界面
        Sleep(16);
    }
    // 转换由 handle_password_input 设置 exitForget 来处理
}

// 主菜单视图
void menuView() {
    // 假设图形已初始化
    // putimage(0, 0, &image_View[0]); // 绘制背景 (在循环中绘制)
    setbkmode(TRANSPARENT); // 设置文本背景透明

    bool exitMenu = false; // 控制是否退出菜单循环
    while (!exitMenu) {
        BeginBatchDraw(); // 开始批量绘制
        putimage(0, 0, &image_View[0]); // 每帧重绘背景

        // --- 绘制按钮 ---
        // 如果可能，使用 UIUtils::button 实现交互和绘制一致性
        // 或者绘制图片并手动检查鼠标点击
        if (image_Button[18].getwidth() > 0) {
            putimage(100, 100, &image_Button[18]);
        }
        if (image_Button[17].getwidth() > 0) {
            putimage(100, 200, &image_Button[17]);
        }
        // 文本按钮 (示例使用 inputText 和手动点击检查)
        inputText("设置", "微软雅黑", 48, WHITE, 100, 300);
        inputText("游戏说明", "微软雅黑", 48, WHITE, 100, 400);
        inputText("仓库", "微软雅黑", 48, WHITE, 100, 500); // 或 "装备"
        inputText("退出游戏", "微软雅黑", 48, WHITE, 100, 600);

        // --- 处理输入 ---
        static ExMessage menuMsg; // 此视图使用的局部消息结构体
        // 使用非阻塞 peekmessage 并移除消息 (remove=true)
        if (peekmessage(&menuMsg, EX_MOUSE | EX_KEY, true)) {
            if (menuMsg.message == WM_LBUTTONDOWN) { // 鼠标左键按下
                // 检查按钮区域 (需要图片加载后才能用 getwidth/getheight)
                if (image_Button[18].getwidth() > 0 && inArea(menuMsg.x, menuMsg.y, 100, 100, image_Button[18].getwidth(), image_Button[18].getheight())) {
                    printf("菜单: 点击了新游戏\n");
                    exitMenu = true;
                    newGame(); // 开始新游戏逻辑
                } else if (image_Button[17].getwidth() > 0 && inArea(menuMsg.x, menuMsg.y, 100, 200, image_Button[17].getwidth(), image_Button[17].getheight())) {
                    printf("菜单: 点击了继续游戏\n");
                    if (loadGame()) { // 尝试加载游戏
                         exitMenu = true;
                         gameView(); // 开始加载的游戏
                    } else {
                         // 显示"加载失败"消息?
                         MessageBox(GetHWnd(), _T("无法加载存档文件！"), _T("加载失败"), MB_OK | MB_ICONWARNING);
                    }
                } else if (inArea(menuMsg.x, menuMsg.y, 100, 300, textwidth("设置"), 50)) { // 估算文本区域
                     printf("菜单: 点击了设置\n");
                     exitMenu = true; setView(); // 进入设置视图
                } else if (inArea(menuMsg.x, menuMsg.y, 100, 400, textwidth("游戏说明"), 50)) { // 估算文本区域
                     printf("菜单: 点击了游戏说明\n");
                     exitMenu = true; describeView(); // 进入说明视图
                } else if (inArea(menuMsg.x, menuMsg.y, 100, 500, textwidth("仓库"), 50)) { // 估算文本区域
                     printf("菜单: 点击了仓库\n");
                     exitMenu = true; storeView(); // 进入仓库视图
                } else if (inArea(menuMsg.x, menuMsg.y, 100, 600, textwidth("退出游戏"), 50)) { // 估算文本区域
                     printf("菜单: 点击了退出游戏\n");
                     exitMenu = true;
                     // 可选: 添加确认对话框
                     // if (MessageBox(GetHWnd(), _T("确定要退出游戏吗?"), _T("退出"), MB_YESNO | MB_ICONQUESTION) == IDYES) {
                          exit(0); // 退出应用程序
                     // } else { exitMenu = false; } // 如果点否，不退出菜单
                }
                 // printf("鼠标点击位置 (%d, %d)\n", menuMsg.x, menuMsg.y); // 调试点击位置
            } else if (menuMsg.message == WM_KEYDOWN && menuMsg.vkcode == VK_ESCAPE) {
                // 可选: Esc 键从菜单退出游戏?
                // exitMenu = true;
                // exit(0);
            }
        }


        EndBatchDraw(); // 结束批量绘制
        Sleep(16); // 防止 CPU 占用过高
    }
     printf("退出 menuView 循环。\n"); // 除非转换视图，否则不应执行到这里
}


// 游戏说明视图
void describeView() {
    // TODO: 实现游戏说明屏幕
    putimage(0, 0, &image_View[0]); // 示例背景
    settextcolor(YELLOW); settextstyle(30, 0, _T("黑体")); setbkmode(TRANSPARENT);
    outtextxy(100, 100, _T("游戏说明"));
    outtextxy(100, 150, _T("WASD键移动飞机。"));
    outtextxy(100, 180, _T("空格键发射子弹。"));
    outtextxy(100, 210, _T("ESC 或 P 键暂停游戏。"));
    outtextxy(100, 240, _T("躲避敌机和子弹，击毁所有敌人获得胜利！"));
    // 添加返回按钮
    if (image_Button[3].getwidth() > 0) {
        drawAlpha(&image_Button[3], 50, 600);
        inputText("返回", "微软雅黑", 30, WHITE, 75, 615);
    }

    ExMessage descMsg;
    while(true) { // 循环直到返回
         // 绘制操作应该在循环内，以防窗口需要重绘
         BeginBatchDraw();
         putimage(0, 0, &image_View[0]);
         settextcolor(YELLOW); settextstyle(30, 0, _T("黑体")); setbkmode(TRANSPARENT);
         outtextxy(100, 100, _T("游戏说明"));
         // ... (重绘其他文本)
         if (image_Button[3].getwidth() > 0) {
            drawAlpha(&image_Button[3], 50, 600);
            inputText("返回", "微软雅黑", 30, WHITE, 75, 615);
         }
         EndBatchDraw();


        if (peekmessage(&descMsg, EX_MOUSE | EX_KEY, true)) { // 获取输入
            if (descMsg.message == WM_LBUTTONDOWN) {
                 // 检查是否点击了返回按钮
                 if (image_Button[3].getwidth() > 0 && inArea(descMsg.x, descMsg.y, 50, 600, image_Button[3].getwidth(), image_Button[3].getheight())) {
                     menuView(); // 返回主菜单
                     return;    // 退出此函数
                 }
            } else if (descMsg.message == WM_KEYDOWN && descMsg.vkcode == VK_ESCAPE) { // 按 Esc 键
                 menuView(); // Esc 也返回主菜单
                 return;    // 退出此函数
            }
        }
        // FlushBatchDraw(); // 如果不用 Begin/EndBatchDraw，需要刷新
        Sleep(16); // 短暂休眠
    }
}

// 设置视图
void setView() {
     // TODO: 实现设置屏幕 (音量、控制等)
     putimage(0, 0, &image_View[0]); // 示例背景
     if (image_Button[13].getwidth() > 0) drawAlpha(&image_Button[13], 490, 100); // 设置标题图片?

     // 示例元素来自原始代码 (需要实际实现)
     inputText("音效", "宋体", 33, RED, 310, 210);
     inputText("音效 1", "宋体", 30, BLUE, 240, 290); // 可能是音效选项
     inputText("选择", "宋体", 30, WHITE, 390, 290); // 可能是选择按钮
     // ... 绘制其他设置元素 ...

     if (image_Button[3].getwidth() > 0) {
        drawAlpha(&image_Button[3], 50, 600);
        inputText("返回", "微软雅黑", 30, WHITE, 75, 615);
     }

     ExMessage setMsg;
     while(true) {
         BeginBatchDraw();
         // 重绘所有元素
          putimage(0, 0, &image_View[0]);
          if (image_Button[13].getwidth() > 0) drawAlpha(&image_Button[13], 490, 100);
          inputText("音效", "宋体", 33, RED, 310, 210);
          inputText("音效 1", "宋体", 30, BLUE, 240, 290);
          inputText("选择", "宋体", 30, WHITE, 390, 290);
          // ... 重绘其他 ...
          if (image_Button[3].getwidth() > 0) {
            drawAlpha(&image_Button[3], 50, 600);
            inputText("返回", "微软雅黑", 30, WHITE, 75, 615);
         }
         EndBatchDraw();


         if (peekmessage(&setMsg, EX_MOUSE | EX_KEY, true)) { // 获取输入
             if (setMsg.message == WM_LBUTTONDOWN) {
                  // 检查返回按钮
                  if (image_Button[3].getwidth() > 0 && inArea(setMsg.x, setMsg.y, 50, 600, image_Button[3].getwidth(), image_Button[3].getheight())) {
                      menuView(); return; // 返回主菜单
                  }
                  // TODO: 处理点击设置选项的逻辑 (例如音量滑块、开关等)
             } else if (setMsg.message == WM_KEYDOWN && setMsg.vkcode == VK_ESCAPE) {
                  menuView(); return; // Esc 返回主菜单
             }
         }
         Sleep(16); // 短暂休眠
     }
}


// 仓库/装备视图
void storeView() {
    // TODO: 实现仓库/装备屏幕
    // 这需要大量逻辑来显示拥有的装备、
    // 处理库存、装备物品到飞机模块等。
    // 原始的 'h' 数组逻辑不清晰，可能需要替换。

    putimage(0, 0, &image_View[0]); // 示例背景
    settextcolor(YELLOW); settextstyle(30, 0, _T("黑体")); setbkmode(TRANSPARENT);
    outtextxy(100, 100, _T("仓库 / 装备"));
    outtextxy(100, 150, _T("功能待实现...")); // 提示功能未完成

    if (image_Button[3].getwidth() > 0) {
        drawAlpha(&image_Button[3], 50, 600);
        inputText("返回", "微软雅黑", 30, WHITE, 75, 615);
    }

    ExMessage storeMsg;
    while(true) {
         BeginBatchDraw();
         // 重绘界面元素
         putimage(0, 0, &image_View[0]);
         settextcolor(YELLOW); settextstyle(30, 0, _T("黑体")); setbkmode(TRANSPARENT);
         outtextxy(100, 100, _T("仓库 / 装备"));
         outtextxy(100, 150, _T("功能待实现..."));
         if (image_Button[3].getwidth() > 0) {
            drawAlpha(&image_Button[3], 50, 600);
            inputText("返回", "微软雅黑", 30, WHITE, 75, 615);
         }
         // 在这里绘制仓库中的物品列表、当前装备等...
         EndBatchDraw();

        if (peekmessage(&storeMsg, EX_MOUSE | EX_KEY, true)) { // 获取输入
            if (storeMsg.message == WM_LBUTTONDOWN) {
                 // 检查返回主菜单按钮
                 if (image_Button[3].getwidth() > 0 && inArea(storeMsg.x, storeMsg.y, 50, 600, image_Button[3].getwidth(), image_Button[3].getheight())) {
                     menuView(); return; // 返回主菜单
                 }
                 // 处理点击装备物品的逻辑 (装备/卸下等)
            } else if (storeMsg.message == WM_KEYDOWN && storeMsg.vkcode == VK_ESCAPE) {
                 menuView(); return; // Esc 返回主菜单
            }
        }
        Sleep(16); // 短暂休眠
    }
}

// 暂停视图 - 逻辑应集成到 gameView
void stopView() {
     // 这个函数似乎旨在作为绘制在 gameView 之上的暂停菜单覆盖层。
     // 它不应该重新初始化图形或拥有自己的循环。
     // 它应该由 gameView 在 gameState 为 GAME_PAUSED 时调用来绘制。
     printf("stopView() 被调用 - 暂停覆盖层应在 gameView 中绘制。\n");

     // 示例覆盖层绘制逻辑 (当 gameView 暂停时调用):
     // IMAGE msg[4]; // 这些图片应该在别处一次性加载?
     // loadimage(msg + 1, "Assets\\暂停\\暂停标题.png"); // 暂停标题图片
     // loadimage(msg + 2, "Assets\\暂停\\继续游戏按钮.png", 160, 80); // 继续按钮
     // loadimage(msg + 3, "Assets\\暂停\\返回主菜单按钮.png", 200, 100); // 返回菜单按钮
     // // 使背景半透明
     // setfillcolor(RGBA(0,0,0,150)); // 需要支持 RGBA 的 easyx 版本或手动 alpha 混合
     // solidrectangle(0, 0, getwidth(), getheight()); // 绘制半透明黑色矩形
     // // 绘制标题和按钮
     // if(!msg[1].is_null()) drawAlpha(msg + 1, 410, 130);
     // if(!msg[2].is_null()) drawAlpha(msg + 2, 370, 500);
     // if(!msg[3].is_null()) drawAlpha(msg + 3, 765, 490);

     // 暂停菜单的输入处理也应该在 gameView 的暂停状态下进行。
}

// 绘制主游戏界面元素
void mapView() {
    // 绘制背景、玩家、敌人、子弹

    // --- 绘制滚动背景 ---
    // 确保背景图片 image_View[7] 已加载且有效
    if (image_View[7].getwidth() > 0 && image_View[7].getheight() > 0) {
        int imgH = image_View[7].getheight();    // 背景图片高度
        int screenH = getheight();             // 屏幕高度
        // 计算当前应该绘制的图片顶部 Y 坐标，使用模运算实现循环滚动
        int currentImgTop = map_y % imgH;
        // 确保 currentImgTop 是负数或零，以便从图片底部开始向上滚动
        if (currentImgTop > 0) currentImgTop -= imgH;

        // 绘制第一部分 (可能从图片中间某行开始绘制到图片底部)
        putimage(0, currentImgTop, getwidth(), imgH, &image_View[7], 0, 0);
        // 在第一部分下方绘制第二部分 (图片的顶部)，以填满屏幕剩余空间，实现无缝滚动
        putimage(0, currentImgTop + imgH, getwidth(), screenH, &image_View[7], 0, 0); // 让第二部分填满剩余屏幕

        map_y += 1; // 控制地图向上滚动的速度 (每帧移动1像素)
        // map_y % imgH 会自动处理回绕，无需手动重置 map_y
    } else {
        // 备用方案: 如果背景图片无效，绘制纯色背景或静态图片
        setfillcolor(BLACK); // 示例: 纯黑背景
        solidrectangle(0, 0, getwidth(), getheight()); // 填充整个屏幕
    }


    // --- 绘制玩家 ---
    // 确保玩家图片 image_Plane[0] 已加载
    if (image_Plane[0].getwidth() > 0) {
        // 使用 drawAlpha 绘制带透明通道的玩家图片
        // 在 player.x, player.y 中心点绘制，需要减去图片宽高的一半
        drawAlpha(&image_Plane[0], player.x - image_Plane[0].getwidth()/2.0f, player.y - image_Plane[0].getheight()/2.0f);
         // 如果需要，添加玩家无敌闪烁效果
         // if (player.isInvincible) {
         //    if ((GetTickCount64() / 100) % 2 == 0) { // 简单的闪烁效果
         //       // 正常绘制或绘制为半透明
         //    } else {
         //       // 跳过绘制或用不同颜色绘制轮廓等
         //    }
         //    // 检查无敌时间是否结束
         //    if (GetTickCount64() - player.invincibleTimer > INVINCIBILITY_DURATION_MS) {
         //       player.isInvincible = false;
         //    }
         // }
    }


    // --- 绘制敌人 ---
    for (int i = 0; i < MAX_TOTAL_ENEMIES; i++) { // 遍历所有可能的敌机槽位
        if (enemies[i].isActive) { // 只绘制活动的敌机
             // 检查图片索引是否有效且图片已加载
             if(enemies[i].num >= 0 && enemies[i].num < MAX_ENEMY_IMAGES && image_Enemy[enemies[i].num].getwidth() > 0) {
                // 使用 drawAlpha 绘制带透明通道的敌机图片 (坐标是左上角)
                drawAlpha(&image_Enemy[enemies[i].num], enemies[i].x, enemies[i].y);
             }
        }
    }

    // --- 绘制子弹 ---
    for (int i = 0; i < MAX_BULLETS; i++) { // 遍历所有子弹槽位
        if (bullets[i].active) { // 只绘制活动的子弹
             // 检查图片索引是否有效且图片已加载
             if(bullets[i].num >= 0 && bullets[i].num < MAX_BULLET_IMAGES && image_Bullet[bullets[i].num].getwidth() > 0) {
                int w = image_Bullet[bullets[i].num].getwidth();  // 获取子弹图片宽度
                int h = image_Bullet[bullets[i].num].getheight(); // 获取子弹图片高度
                // 子弹通常不需要透明绘制，putimage 效率可能更高
                // 在子弹中心点 (bullets[i].x, bullets[i].y) 绘制，需偏移半个宽高
                putimage(bullets[i].x - w/2.0f, bullets[i].y - h/2.0f, &image_Bullet[bullets[i].num]);
                // 如果子弹图片本身是带透明通道的 PNG，并且你想保留透明效果，
                // 且背景复杂，可以使用 drawAlpha
                // drawAlpha(&image_Bullet[bullets[i].num], bullets[i].x - w/2.0f, bullets[i].y - h/2.0f);
             }
        }
    }
     // --- 绘制爆炸/特效 ---
     // update_and_draw_effects(); // 如果有特效系统，在此处更新和绘制
}

// 根据游戏状态绘制覆盖层文本/按钮 (暂停, 结束, 胜利)
void draw_game_state_overlay(int gameState) { // gameState 是 gameView 中的枚举值
     // gameState: 0=RUNNING, 1=PAUSED, 2=OVER, 3=VICTORY (假设)
     if (gameState == 1) { // GAME_PAUSED
         settextcolor(YELLOW); settextstyle(40, 0, _T("黑体")); setbkmode(TRANSPARENT);
         outtextxy(getwidth()/2 - 100, getheight()/2 - 60, _T("游戏暂停"));
         settextstyle(25, 0, _T("黑体")); settextcolor(WHITE);
         outtextxy(getwidth()/2 - 120, getheight()/2 + 0, _T("按 P 或 ESC 继续"));
         outtextxy(getwidth()/2 - 120, getheight()/2 + 40, _T("按 S 保存游戏"));
         // 考虑在此处添加"返回主菜单"选项
         outtextxy(getwidth()/2 - 120, getheight()/2 + 80, _T("按 M 返回主菜单"));
     } else if (gameState == 2) { // GAME_OVER
         settextcolor(RED); settextstyle(60, 0, _T("黑体")); setbkmode(TRANSPARENT);
         outtextxy(getwidth()/2 - 180, getheight()/2 - 60, _T("游戏结束"));
         settextstyle(25, 0, _T("黑体")); settextcolor(WHITE);
         outtextxy(getwidth()/2 - 150, getheight()/2 + 30, _T("按任意键返回主菜单"));
         // printf("正在绘制 GAME OVER 屏幕\n"); // 调试信息
     } else if (gameState == 3) { // GAME_VICTORY
          settextcolor(GREEN); settextstyle(60, 0, _T("黑体")); setbkmode(TRANSPARENT);
          outtextxy(getwidth()/2 - 180, getheight()/2 - 60, _T("游戏胜利!"));
          settextstyle(25, 0, _T("黑体")); settextcolor(WHITE);
          outtextxy(getwidth()/2 - 150, getheight()/2 + 30, _T("按任意键继续")); // 或返回菜单
         // printf("正在绘制 VICTORY 屏幕\n"); // 调试信息
     }
}


// --- 独立的视图函数 (如果逻辑未完全集成到 gameView 覆盖层中) ---

// 胜利视图 (独立屏幕)
void victoryView() {
    // initgraph(640, 480); // 不应重新初始化图形
    // setbkcolor(WHITE); cleardevice();

    bool exitVic = false; // 控制是否退出此视图
    ExMessage vicMsg;

    while (!exitVic) {
        BeginBatchDraw(); // 开始绘制
        vic_drawBackground(); // 绘制胜利屏幕的特定背景/元素

        // 处理交互 - 例如: 返回菜单或进入下一关
         if (peekmessage(&vicMsg, EX_MOUSE | EX_KEY, true)) { // 获取输入
             // 检查按钮点击 (按钮区域在 vic_drawBackground 中定义)
             if (vicMsg.message == WM_LBUTTONDOWN) {
                 if (inArea(vicMsg.x, vicMsg.y, 180, 360, 280, 90)) { // 返回菜单按钮区域?
                     exitVic = true; menuView(); // 退出并返回主菜单
                 } else if (inArea(vicMsg.x, vicMsg.y, 340, 240, 260, 90)) { // 下一关按钮区域?
                      exitVic = true;
                      current_level++; // 增加关卡编号
                      // 检查是否超过最大关卡数
                      if (current_level > 8) {
                          // 显示游戏通关屏幕或循环?
                          printf("所有关卡完成！\n");
                          // 可以显示一个最终的通关画面
                          // showGameCompleteView();
                          menuView(); // 暂时返回主菜单
                      } else {
                          gameView(); // 开始下一关
                      }
                 }
                 // 添加其他按钮检查 (例如，加载存档槽)
             } else if (vicMsg.message == WM_KEYDOWN) { // 任意键按下
                 exitVic = true; menuView(); // 任何键暂时都返回主菜单
             }
         }
         EndBatchDraw(); // 结束绘制
         Sleep(16); // 短暂休眠
    }
}

// 关卡结束奖励视图
void boxView() {
     // TODO: 实现关卡结束奖励/物品箱屏幕
     putimage(0, 0, &image_View[0]); // 背景
     setbkmode(TRANSPARENT);
     inputText("关卡完成!", "微软雅黑", 48, RGB(240, 155, 89), 540, 150); // 标题
     inputText("获得奖励: [待实现]", "微软雅黑", 30, WHITE, 500, 250); // 奖励文本

     // 按钮: 继续 (下一关/菜单), 仓库, 重玩?
     if (image_Button[9].getwidth() > 0) drawAlpha(&image_Button[9], 70, 530);  // "返回主菜单" 按钮?
     if (image_Button[14].getwidth() > 0) drawAlpha(&image_Button[14], 1000, 530); // "下一关" 按钮?
     // if(!image_Button[?].is_null()) drawAlpha(&image_Button[?], 500, 530); // "仓库" 按钮?

     ExMessage boxMsg;
     while(true) {
         BeginBatchDraw();
         // 重绘元素
          putimage(0, 0, &image_View[0]);
          setbkmode(TRANSPARENT);
          inputText("关卡完成!", "微软雅黑", 48, RGB(240, 155, 89), 540, 150);
          inputText("获得奖励: [待实现]", "微软雅黑", 30, WHITE, 500, 250);
          if (image_Button[9].getwidth() > 0) drawAlpha(&image_Button[9], 70, 530);
          if (image_Button[14].getwidth() > 0) drawAlpha(&image_Button[14], 1000, 530);
          // 重绘仓库按钮...
         EndBatchDraw();

         if (peekmessage(&boxMsg, EX_MOUSE | EX_KEY, true)) { // 获取输入
             if (boxMsg.message == WM_LBUTTONDOWN) { // 鼠标点击
                  // 检查返回主菜单按钮
                  if (image_Button[9].getwidth() > 0 && inArea(boxMsg.x, boxMsg.y, 70, 530, image_Button[9].getwidth(), image_Button[9].getheight())) {
                      menuView(); return; // 返回主菜单
                  }
                  // 检查下一关按钮
                  else if (image_Button[14].getwidth() > 0 && inArea(boxMsg.x, boxMsg.y, 1000, 530, image_Button[14].getwidth(), image_Button[14].getheight())) {
                       // 进入下一关
                       current_level++;
                       if (current_level > 8) {
                           printf("所有关卡完成！\n"); menuView();
                       } else {
                           gameView();
                       }
                       return;
                  }
                  // 添加仓库按钮点击 -> storeView()
             } else if (boxMsg.message == WM_KEYDOWN && boxMsg.vkcode == VK_ESCAPE) {
                  menuView(); return; // Esc 返回主菜单
             }
         }
         Sleep(16); // 短暂休眠
     }
}

// 失败视图 (独立屏幕，如果 gameView 中的覆盖层不够用)
void defeatView() {
    // initgraph(640, 480); // 不应重新初始化
    // setbkcolor(WHITE); cleardevice(); // 可以在此清理

    // 绘制 "游戏结束" 和分数
    BeginBatchDraw(); // 使用批处理绘图
    cleardevice(); // 清屏
    settextcolor(RED); settextstyle(60, 0, _T("黑体")); setbkmode(TRANSPARENT);
    outtextxy(getwidth()/2 - 180, getheight()/2 - 60, _T("游戏结束"));
    TCHAR scoreText[50];
    _stprintf_s(scoreText, _T("最终得分: %d"), player.score);
    settextcolor(WHITE); settextstyle(30, 0, _T("黑体"));
    outtextxy(getwidth()/2 - 120, getheight()/2 + 20, scoreText);
    outtextxy(getwidth()/2 - 150, getheight()/2 + 70, _T("按任意键返回主菜单"));
    EndBatchDraw(); // 显示绘制内容
    // FlushBatchDraw(); // 如果不用 Begin/EndBatchDraw

    _getch(); // 等待任意键按下 (阻塞式)
    menuView(); // 返回主菜单
}

// --- 视图辅助函数实现 ---

// 绘制 victoryView 的背景和元素
void vic_drawBackground() {
    IMAGE vic_setting; // 考虑只加载一次这些图片
    loadimage(&vic_setting, "Assets\\Image\\View\\7.png", 640, 480); // 特定尺寸?
    if (vic_setting.getwidth() > 0) drawAlpha(&vic_setting, 0, 0);

    IMAGE vic; // 胜利横幅
    loadimage(&vic, "Assets\\Image\\Button\\2.png", 320, 90);
    if (vic.getwidth() > 0) drawAlpha(&vic, 190, 50);

    // 按钮
    IMAGE button[3];
    loadimage(&button[0], "Assets\\Image\\Button\\10.png", 280, 90); // 返回菜单
    // loadimage(&button[1], "Assets\\Image\\Button\\10.png", 260, 90); // 下一关? (使用相同图片?) -> 应使用不同图片索引
    loadimage(&button[1], "Assets\\Image\\Button\\11.png", 260, 90); // 假设 11 是下一关
    loadimage(&button[2], "Assets\\Image\\Button\\24.png", 260, 90); // 选择存档?
    if (button[0].getwidth() > 0) drawAlpha(&button[0], 180, 360); // 返回菜单位置
    if (button[1].getwidth() > 0) drawAlpha(&button[1], 340, 240); // 下一关位置
    if (button[2].getwidth() > 0) drawAlpha(&button[2], 40, 240);  // 选择存档位置

    // 分数显示
    settextstyle(30, 0, "微软雅黑"); settextcolor(RED); setbkmode(TRANSPARENT);
    char str[50];
    sprintf_s(str, "最终得分: %d 分", player.score);
    outtextxy(250, 200, str);
}


// 绘制注册屏幕的背景和静态元素
void draw_Register_Again(IMAGE registerImage[]) {
    // 假设 registerImage 数组已正确加载
    // BeginBatchDraw(); // 不应在这里调用，应由调用者管理批处理
    // Set background? cleardevice(); ? 取决于调用位置
    setbkmode(TRANSPARENT); // 设置文本背景透明

    // 绘制背景图
    if (registerImage[0].getwidth() > 0) drawAlpha(&registerImage[0], 0, 0);

    // 绘制按钮和输入框背景 (使用 drawAlpha 支持 PNG 透明)
    if (registerImage[1].getwidth() > 0) { // 假设是按钮图片
        drawAlpha(&registerImage[1], 450, 480); // 返回按钮?
        drawAlpha(&registerImage[1], 650, 480); // 确认按钮?
    }
     if (registerImage[2].getwidth() > 0) { // 假设是标题背景
        drawAlpha(&registerImage[2], 550, 75);
     }
     if (registerImage[3].getwidth() > 0) { // 假设是输入框背景
        drawAlpha(&registerImage[3], 430, 250); // 用户名框背景
        drawAlpha(&registerImage[3], 430, 325); // 密码框背景
        drawAlpha(&registerImage[3], 430, 400); // 确认密码框背景
     }


    // 绘制静态文本标签
    settextstyle(13, 8, "圆体"); settextcolor(RGB(1, 1, 1));
    outtextxy(475, 520, "返回登录界面");
    outtextxy(710, 522, "确认");
    outtextxy(585, 107, "新用户注册");
    settextstyle(30, 10, "微软雅黑");
    outtextxy(375, 250, "账号");
    outtextxy(375, 325, "密码");
    outtextxy(290, 400, "确认密码");

    // Don't call EndBatchDraw here
}

// 绘制修改密码界面的交互元素
void password_draw() {
    BeginBatchDraw(); // 开始批处理
    // cleardevice(); // 在调用它的循环中清屏
    drawBackground(); // 绘制静态背景和标签

    // 绘制输入框 (边框和文本)
    for (int i = 0; i < 3; i++) {
        setfillcolor(WHITE); // 输入框背景色
        setlinecolor(BLACK); // 默认边框色
        setlinestyle(PS_SOLID, 1); // 默认边框样式
        if (i == curr_flag_password) { // 高亮选中的输入框
            setlinecolor(RED);
            setlinestyle(PS_SOLID, 2); // 粗一点的边框
        }
        fillrectangle(rect_password[i].left, rect_password[i].top, rect_password[i].right, rect_password[i].bottom);
        rectangle(rect_password[i].left, rect_password[i].top, rect_password[i].right, rect_password[i].bottom);

        // 绘制文本 (密码字段用星号屏蔽)
        //char displayText[textlen_max] = { '\0' };
        char displayText[256] = { '\0' };
        if (i == 0) { // 账号字段 - 显示原文
             strncpy_s(displayText, text_password[i], textlen_max - 1);
        } else { // 密码字段 - 显示星号
             int len = curr_len_password[i];
             for(int k=0; k<len && k < textlen_max -1; ++k) displayText[k] = '*';
             displayText[len] = '\0';
        }
        // 在输入框内左对齐、垂直居中绘制文本
        drawtext(displayText, &rect_password[i], DT_LEFT | DT_VCENTER | DT_SINGLELINE);
    }

    // 绘制按钮交互高亮 (如果鼠标悬停)
     static ExMessage pwdDrawMsg; // 局部消息副本
     peekmessage(&pwdDrawMsg, EX_MOUSE); // 非阻塞检查鼠标位置
     if (inArea(pwdDrawMsg.x, pwdDrawMsg.y, 60, 360, 160, 60)) { // 返回按钮区域
         setlinecolor(RED); // 绘制红色高亮框
         rectangle(60, 360, 220, 420);
     }
     if (inArea(pwdDrawMsg.x, pwdDrawMsg.y, 250, 360, 160, 60)) { // 确认按钮区域
         setlinecolor(RED); // 绘制红色高亮框
         rectangle(250, 360, 410, 420);
     }

    EndBatchDraw(); // 结束批处理
}

// 绘制修改密码界面的静态背景元素
void drawPasswordChangeBackground() { // 改成这样
    IMAGE forget_setting;
    loadimage(&forget_setting, "Assets\\register\\注销背景.png", 450, 450);
    if (forget_setting.getwidth() > 0) drawAlpha(&forget_setting, 0, 0);

    IMAGE Yes; // 确认按钮图
    loadimage(&Yes, "Assets\\Image\\Button\\17.png", 160, 60);
    if (Yes.getwidth() > 0) drawAlpha(&Yes, 250, 360);

    IMAGE return_menu; // 返回按钮图
    loadimage(&return_menu, "Assets\\Image\\Button\\10.png", 160, 60);
    if (return_menu.getwidth() > 0) drawAlpha(&return_menu, 60, 360);

    // 标题文本
    char str[50] = "修改密码";
    setbkmode(TRANSPARENT); // 文本背景透明
    // 使用 UI 工具函数绘制文本
    inputText(str, "微软雅黑", 50, YELLOW, 125, 50); // 调整位置/大小

    // 输入字段的静态标签文本
    inputText("账号:", "微软雅黑", 20, RED, 65, 200);
    // 根据服务器协议，这里可能是"旧密码"或不需要
    inputText("旧密码:", "微软雅黑", 20, RED, 55, 250);
    inputText("新密码:", "微软雅黑", 20, RED, 55, 300);

    // 输入框的背景在 password_draw 中绘制，这里不需要绘制
}


// 绘制登录屏幕的静态背景元素
void login_drawBackground() {
    IMAGE login_setting; // 背景图
    loadimage(&login_setting, "Assets\\register\\注销背景.png", 640, 480);
    if (login_setting.getwidth() > 0) drawAlpha(&login_setting, 0, 0);

    int bw = 180, bh = 70; // 按钮尺寸
    IMAGE button[3]; // 按钮图片
    loadimage(button, "Assets\\Image\\Button\\9.png", bw, bh);  // 注册按钮
    loadimage(button + 1, "Assets\\Image\\Button\\17.png", bw, bh); // 登录按钮
    loadimage(button + 2, "Assets\\Image\\Button\\8.png", bw, bh); // 忘记密码按钮
    if (button[0].getwidth() > 0) drawAlpha(button, 25, 330);      // 绘制注册按钮
    if (button[1].getwidth() > 0) drawAlpha(button + 1, 230, 330); // 绘制登录按钮
    if (button[2].getwidth() > 0) drawAlpha(button + 2, 435, 330); // 绘制忘记密码按钮

    // 标题
    inputText("登录", "微软雅黑", 50, BLACK, 270, 90);

    // 输入字段标签
    inputText("用户名:", "圆体", 20, RED, 100, 170); // 调整了标签位置
    inputText("密码:", "圆体", 20, RED, 120, 240);   // 调整了标签位置

    // 输入框背景在 login_draw 中绘制
}

// 绘制登录屏幕的交互元素 (输入框, 高亮)
void login_draw() {
    BeginBatchDraw(); // 开始批处理
    // cleardevice(); // 清屏应在调用它的循环 (logView) 中完成
    login_drawBackground(); // 重绘静态背景和标签

    // 绘制输入框
    for (int i = 0; i < 2; i++) {
        setfillcolor(WHITE); // 输入框背景色
        setlinecolor(BLACK); // 默认边框色
        setlinestyle(PS_SOLID, 1); // 默认边框样式
        if (i == login_curr_flag) { // 高亮当前选中的输入框
            setlinecolor(RED);
            setlinestyle(PS_SOLID, 2); // 粗边框
        }
        // 绘制输入框背景和边框
        fillrectangle(rect_login[i].left, rect_login[i].top, rect_login[i].right, rect_login[i].bottom);
        rectangle(rect_login[i].left, rect_login[i].top, rect_login[i].right, rect_login[i].bottom);

        // 绘制输入框中的文本 (密码字段用星号屏蔽)
        //char displayText[textlen_max] = { '\0' };
        char displayText[256] = { '\0' };
        if (i == 0) { // 用户名
             strncpy_s(displayText, login_text[i], textlen_max - 1);
        } else { // 密码
             int len = login_curr_len[i];
             for(int k=0; k<len && k < textlen_max -1; ++k) displayText[k] = '*'; // 用星号填充
             displayText[len] = '\0';
        }
        // 在输入框内左对齐、垂直居中绘制文本
        drawtext(displayText, &rect_login[i], DT_LEFT | DT_VCENTER | DT_SINGLELINE);
    }

    // 绘制按钮交互高亮 (可选, 也可以用 UIUtils::button)
     static ExMessage loginDrawMsg; // 局部消息副本
     peekmessage(&loginDrawMsg, EX_MOUSE); // 非阻塞检查鼠标位置
     if (inArea(loginDrawMsg.x, loginDrawMsg.y, 25, 330, 180, 70)) { // 注册按钮区域
         setlinecolor(RED); rectangle(25, 330, 205, 400); // 绘制高亮框
     }
     if (inArea(loginDrawMsg.x, loginDrawMsg.y, 230, 330, 180, 70)) { // 登录按钮区域
         setlinecolor(RED); rectangle(230, 330, 410, 400);
     }
     if (inArea(loginDrawMsg.x, loginDrawMsg.y, 435, 330, 180, 70)) { // 忘记密码按钮区域
         setlinecolor(RED); rectangle(435, 330, 615, 400);
     }

    EndBatchDraw(); // 结束批处理
}

// 绘制注册视图中的输入框
void draw() {
    // 这个函数应该在 registerView 的绘制循环内部被调用
    // 并且在 BeginBatchDraw / EndBatchDraw 之间。

    // BeginBatchDraw(); // 如果在外部调用，移除这里的 Begin/End

    // 绘制 3 个输入框
    for (int i = 0; i < 3; i++) {
        setfillcolor(WHITE); // 背景色
        setlinecolor(BLACK); // 默认边框
        setlinestyle(PS_SOLID, 1);
        if (i == curr_flag) { // 高亮选中框
            setlinecolor(RED);
            setlinestyle(PS_SOLID, 2);
        }
        // 绘制背景和边框
        fillrectangle(rect[i].left, rect[i].top, rect[i].right, rect[i].bottom);
        rectangle(rect[i].left, rect[i].top, rect[i].right, rect[i].bottom);

        // 绘制文本 (密码用星号)
         //char displayText[max_len + 1] = { '\0' }; // 使用 max_len
         char displayText[10 + 1] = { '\0' }; // 使用 max_len
         if (i == 0) { // 用户名
              strncpy_s(displayText, text[i], max_len);
         } else { // 密码和确认密码
              int len = curr_len[i];
              for(int k=0; k<len && k < max_len; ++k) displayText[k] = '*';
              displayText[len] = '\0';
         }
         // 左对齐、垂直居中绘制
        drawtext(displayText, &rect[i], DT_LEFT | DT_VCENTER | DT_SINGLELINE);
    }

    // EndBatchDraw(); // 如果在外部调用，移除这里的 Begin/End
}
